#pragma once
#include <iostream>
#include <cassert>
namespace wxd
{
    // 先描述
    template <class T>
    class list_node
    {
    public:
        // 默认构造
        list_node(const T &val = T()) : _data(val), _next(nullptr), _prev(nullptr)
        {
        }

        T _data;
        list_node *_next;
        list_node *_prev;
    };

    template <class T, class Ref, class Ptr>
    class list_iterator
    {
    public:
        typedef list_node<T> Node;
        typedef list_iterator<T, Ref, Ptr> Self;
        // 测试没有默认构造
        list_iterator(Node *node) : _node(node) {};

        Ref operator*()
        {
            return _node->_data;
        }

        // 前置++
        Self &operator++()
        {
            _node = _node->_next;
            return *this;
        }
        // 后置++
        Self operator++(int)
        {
            Node *tmp = _node;
            _node = _node->_next;
            return _node;
        }

        // 前置--
        Self &operator--()
        {
            _node = _node->_prev;
            return *this;
        }
        // 后置--
        Self operator--(int)
        {
            Node *tmp = _node;
            _node = _node->_prev;
            return _node;
        }

        Ptr operator->()
        {
            return &(_node->_data);
        }

        bool operator!=(const Self &self)
        {
            return _node != self._node;
        }

        Node *_node;
    };

    // 再组织
    template <class T>
    class list
    {
    public:
        typedef list_node<T> Node;
        typedef list_iterator<T, T &, T *> iterator;
        typedef list_iterator<T, const T &, const T *> const_iterator;

        iterator begin()
        {
            return _head->_next;
        }
        iterator end()
        {
            return _head;
        }
        const_iterator begin() const
        {
            return _head->_next;
        }
        const_iterator end() const
        {
            return _head;
        }

        // 构造函数
        list() : _head(new Node), _size(0)
        {
            //printf("%p\n",_head);
            
            // 初始的头结点的_next和_prev都是指向自身的
            _head->_next = _head->_prev = _head;
        }

        //拷贝构造
        list(const list& l): _head(new Node), _size(0)
        {
            _head->_next = _head->_prev = _head;
            //printf("%p\n",_head);
            for(auto& x:l)
            {
                //std::cout<<"x = "<<x<<" "<<std::endl;
                push_back(x);
            }
        }

        void swap(list& l)
        {
            std::swap(_head,l._head);
            std::swap(_size,l._size);
        }

        //赋值操作符
        list& operator=(list l)
        {
            swap(l);
            return *this;
        }

        void push_back(const T &val);
        size_t size()
        {
            return _size;
        }
        bool empty()
        {
            return _size == 0;
        }
        iterator erase(iterator pos);
        iterator insert(iterator pos, const T &val);
        void pop_back();
        void pop_front();
        void clear();

        ~list()
        {
            clear();
            delete _head;
            _head = nullptr;
            _size = 0;
        }

    private:
        Node *_head;
        size_t _size;
    };

    template <class T>
    void list<T>::push_back(const T &val)
    {
        // 取值
        //std::cout<<"val = "<<val<<std::endl;
        Node *new_node = new Node(val);
        //printf("new_node = %p\n",new_node);
        // printf("%p\n", _head);
        //  插入
        _head->_prev->_next = new_node;
        new_node->_prev = _head->_prev;
        new_node->_next = _head;
        _head->_prev = new_node;

        _size++;
    }

    template <class T>
    typename list<T>::iterator list<T>::erase(iterator pos)
    {
        assert(size() != 0);
        Node *prev = pos._node->_prev;
        Node *next = pos._node->_next;

        prev->_next = next;
        next->_prev = prev;
        delete pos._node;
        _size--;
        return next;
    }

    template<class T>
    typename list<T>::iterator list<T>::insert(iterator pos, const T &val)
    {
        // 申请结点
        Node *new_node = new Node(val);
        // 链接
        Node *prev = pos._node->_prev;
        prev->_next = new_node;
        new_node->_prev = prev;
        new_node->_next = pos._node;
        pos._node->_prev = new_node;
        _size++;
        return new_node;
    }

    template<class T>
    void list<T>::pop_back()
    {
        // assert(size() != 0);
        // Node* prev = _head->_prev->_prev;
        // Node* del = _head->_prev;
        // prev->_next = _head;
        // _head->_prev = prev;
        // delete del;

        erase(_head->_prev);
    }

    template<class T>
    void list<T>::pop_front()
    {
        assert(size() != 0);

        erase(_head->_next);
    }


    template<class T>
    void list<T>::clear()
    {
        iterator it = begin();
        while(it != end())
        {
            it = erase(it);
        }
    }


};